package edu.stanford.prpl.api;

import java.io.InputStream;
import java.net.URL;
import java.util.List;

public interface PRPLObjectManager {

	ResourceManager getResourceManager();

	BlobManager getBlobManager();

	GroupManager getGroupManager();

	IdentityManager getIdentityManager();

	Identity getOwnIdentity();

	public interface BlobManager {

		public static final String BLOB_OP_READ = "R";
		public static final String BLOB_OP_WRITE = "W";

		public static final String BLOB_WATCH_READ = "R";
		public static final String BLOB_WATCH_WRITE = "W";
		public static final String BLOB_WATCH_ANY = "RW";

		// SourceURIMapper getSourceURIMapper();

		String getResourceBlobContentHash(String resourceURI);

		long getResourceBlobLastModifiedDate(String resourceURI);

		Device getResourceBlobServerDevice(String resourceURI);

		// String getResourceBlobServerDevice(String resourceURI);

		long getResourceBlobSize(String resourceURI);

		String getResourceBlobSourceURI(String resourceURI);

		String getResourceBlobMimeType(String resourceURI);

		boolean setResourceBlobMimeType(String resourceURI, String mimeType);

		boolean removeResourceBlob(String resourceURI);

		boolean setResourceBlobContentHash(String resourceURI, String contentHash);

		boolean setResourceBlobLastModifiedDate(String resourceURI, long date);

		boolean setResourceBlobSize(String resourceURI, long size);

		boolean setResourceBlobSourceURI(String resourceURI, String sourceURI);

		// Added FS-like interface

		InputStream getResourceBlob(String resourceURI);

		InputStream getResourceBlob(URL blobServerURL, String resourceURI);

		boolean setResourceBlob(String resourceURI, InputStream inputStream);

		boolean setResourceBlob(URL blobServerURL, String resourceURI, InputStream inputStream);

		/**
		 * @param resourceURI
		 * @param startPosition
		 *            starting offset. If -1, end of file (append)
		 * @param len
		 * @return
		 */
		byte[] getResourceBlob(String resourceURI, int startPosition, int len);

		boolean setResourceBlob(String resourceURI, int startPosition, byte[] b);

		byte[] getResourceBlob(URL blobServerURL, String resourceURI, int startPosition, int len);

		boolean setResourceBlob(URL blobServerURL, String resourceURI, int startPosition, byte[] b);

		// added for PRPLTalk project
		boolean setResourceBlobWatcher(String resourceURI, String watchMode, String callbackURL);

		boolean removeResourceBlobWatcher(String resourceURI, String watchMode, String callbackURL);
	}

	public interface GroupManager {

		boolean addIdentityToGroup(String groupURI, String identityURI);

		Group createGroup(String groupName);

		Group getGroupByName(String groupName);

		Group getGroupByURI(String groupURI);

		Group getPublicGroup();

		Identity[] getAllGroupMembers(String groupURI);

		Group[] getAllGroups();

		String getGroupName(String groupURI);

		boolean isIdentityGroupMember(String groupURI, String identityURI);

		boolean removeIdentityFromGroup(String groupURI, String identityURI);

		boolean removeGroup(String groupURI);

	}

	public interface IdentityManager {

		Identity[] getAllIdentities();

		Group[] getAllGroupsForIdentity(String identityURI);

		Identity getIdentityByURI(String identityURI, boolean create);

		Identity getIdentityByKey(String key);

		String getIdentityName(String identityURI);

		String getIdentityKey(String identityURI);

		boolean setIdentityName(String identityURI, String name);

		boolean removeIdentity(String identityURI);
	}

	public interface ResourceManager {

		public static final String RESOURCE_READ_SHARE = "R";
		public static final String RESOURCE_WRITE_SHARE = "W";

		BlobResource createBlobResource();

		BlobResource createBlobResource(String deviceURI);

		Resource createResource();

		Group[] getAllGroupsSharing(String resourceURI);

		Identity[] getAllIdentitiesSharing(String resourceURI);

		List<BlobResource> getAllBlobResources();

		List<Resource> getAllResources();

		List<Resource> getAllResourcesByPropertyValue(String propertyURI, Object value);

		List<Resource> getAllResourcesFrom(String identityURI);

		List<Resource> getAllResourcesSharedWithGroup(String groupURI);

		List<Resource> getAllResourcesSharedWithIdentity(String identityURI);

		BlobResource getBlobResource(String resourceURI);

		Resource getResource(String resourceURI);

		Identity getResourceOwner(String resourceURI);

		boolean isOwn(String resourceURI);

		QueryResultIterator runQuery(String query);

		QueryResultIterator runQuery(String query, QueryResultIterator.Solution initialBinding);

		boolean checkAccessGroupURI(String resourceURI, String groupURI);

		boolean checkAccessIdentityURI(String resourceURI, String identityURI);

		boolean destroyResource(String resourceURI);

		boolean isBlobResource(String resourceURI);

		boolean shareResourceWithGroups(String resourceURI, String... groupURIs);

		boolean shareResourceWithIdentities(String resourceURI, String... identityURIs);

		boolean unshareResourceWithGroups(String resourceURI, String... groupURIs);

		boolean unshareResourceWithIdentities(String resourceURI, String... identityURIs);

		// Meta methods

		boolean addResourceMetaData(String resourceURI, String propertyURI, Object... values);

		boolean addResourceTags(String resourceURI, String... values);

		boolean addResourceType(String resourceURI, String typeURI);

		Object[] getResourceMetaData(String resourceURI, String propertyURI);

		String[] getResourceMetaDataProperties(String resourceURI);

		long getResourceMetaLastModifiedDate(String resourceURI);

		String getResourceName(String resourceURI);

		String[] getResourceTags(String resourceURI);

		String[] getResourceTypes(String resourceURI);

		boolean removeResourceMetaData(String resourceURI, String propertyURI, Object... values);

		boolean removeResourceTags(String resourceURI, String... values);

		boolean removeResourceType(String resourceURI, String typeURI);

		boolean setResourceMetaData(String resourceURI, String propertyURI, Object... values);

		boolean setResourceMetaLastModifiedDate(String resourceURI, long date);

		boolean setResourceName(String resourceURI, String name);
	}
}
